package com.itheima.aspect;

import cn.hutool.json.JSONUtil;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.utils.CurrentHolder;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

/**
 * @author: zhengsuyang
 * @Desc:
 * @create: 2025-09-14 15:12
 **/
@Slf4j
@Component
@Aspect // CGLib动态代理
public class RecordLogAspect {
    @Autowired
    private OperateLogMapper operateLogMapper;
    @Around("execution(* com.itheima.service.impl.*.update*(..))")
    public Object recordLog(ProceedingJoinPoint pjp) throws Throwable {
        OperateLog operateLog = new OperateLog();
        // 1.记录方法执行开始时间
        long begin = System.currentTimeMillis();
        // 2. 执行原始方法获取返回值
        Object object = null;
        try {
            object = pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        // 获取类名
        String className = pjp.getTarget().getClass().getName();
        // 获取方法名
        MethodSignature signature = (MethodSignature)pjp.getSignature();
        String methodName = signature.getMethod().getName();
        // 获取参数
        Object[] args = pjp.getArgs();
        // 3.记录方法执行结束时间
        long end = System.currentTimeMillis();
        log.info( "{}的{}方法执行的耗时:{}ms", className,methodName,end - begin);

        // 给实体赋值
        operateLog.setOperateTime(LocalDateTime.now());
        operateLog.setOperateEmpId(getCurrentUserId());
        operateLog.setClassName(className);
        operateLog.setMethodName(methodName);
        if (args!=null&&args.length>0)
            operateLog.setMethodParams(JSONUtil.toJsonStr(args));
        if (object!=null)
            operateLog.setReturnValue(JSONUtil.toJsonStr(object));
        else
            operateLog.setReturnValue("void");
        operateLog.setCostTime(end - begin);
        operateLogMapper.insert(operateLog);
        return object;
    }

    public Integer getCurrentUserId(){
        return CurrentHolder.getUserId();
    }
}
